package com.offdissys.common.utils.token;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.offdissys.common.utils.domain.BaseTokenObj;
import com.offdissys.common.utils.domain.TokenConstants;

/**
 * @author ZhangHaiWen
 * @title: AbstractToken
 * @projectName parent
 * @description: Token类
 * @date 2022/3/710:35
 */
public abstract class AbstractToken {

    private TokenConfig tokenConfig;

    public AbstractToken(){
        this.tokenConfig = new DefaultConfig();
    }

    public AbstractToken(TokenConfig tokenConfig){
        this.tokenConfig = tokenConfig;
    }

    /**
     * token构建方法
     * @param t
     * @return
     */
    public abstract <T extends BaseTokenObj> String buildToken(T t);

    /**
     * token解析方法
     * @param tokenStr
     * @param tClass
     * @param <T>
     * @return
     */
    public abstract <T extends BaseTokenObj> T analysisToken(String tokenStr,Class<T> tClass);

    /**
     * 组装缓存key
     * @param t
     * @return
     */
    public final <T extends BaseTokenObj> String buildCatchHeadKey(T t){
        String cacheHeadKey = tokenConfig.cacheHead();
        if(StrUtil.isBlank(cacheHeadKey)){
            cacheHeadKey = TokenConstants.DEFAULT_CACHE_HEAR;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(cacheHeadKey)
                .append(TokenConstants.SEPARATOR)
                .append(t.getKey());
        return sb.toString();
    }

    /**
     * 创建缓存并且保存
     * @return
     */
    public final String createAndCache(BaseTokenObj obj){
        // 创建token前缀
        String token = buildToken(obj);
        // 说明不需要缓存（没有设置缓存cacheService）
        if(ObjectUtil.isEmpty(tokenConfig.cacheService())){
            return token;
        }
        // 将有效天转化为秒
        Long seconds = Long.valueOf(tokenConfig.offsetDay()*24*3600);
        String cacheHeadKey = buildCatchHeadKey(obj);
        tokenConfig.cacheService().expire(cacheHeadKey, token, seconds);
        return token;
    }

    /**
     * 解析token得到对象bean
     * @return
     */
    public final <T extends BaseTokenObj> T analysis(String tokenStr,Class<T> tClass){
        return this.analysisToken(tokenStr,tClass);
    }

    /**
     * 检查缓存是否过期
     * 1.校验token是否失效
     *  1.1 解析 token 查看是否失效
     *  1.2 判断 缓存 中的token是否失效
     * @return
     */
    public final <T extends BaseTokenObj> boolean checkToken(String tokenStr,Class<T> tClass){
        if(StrUtil.isBlank(tokenStr)){
            return false;
        }
        // 1.校验token是否失效
        // 1.1 解析 token 查看是否失效
        T analysisBean = analysis(tokenStr, tClass);
        if(ObjectUtil.isNotEmpty(tokenConfig.cacheService())){
            // 1.2 没有设置缓存cacheService
            String cacheHeadKey = buildCatchHeadKey(analysisBean);
            Object o = tokenConfig.cacheService().get(cacheHeadKey);
            if(ObjectUtil.isEmpty(o)){
                return false;
            }
        }
        return false;
    }

    /**
     * 清空缓存中的token
     * @return
     */
    public final <T extends BaseTokenObj> boolean removeToken(String tokenStr,Class<T> tClass){
        if(StrUtil.isBlank(tokenStr)){
            return true;
        }
        // 1.解析token得到 缓存中的key
        T analysis = analysis(tokenStr, tClass);
        if(ObjectUtil.isNotEmpty(tokenConfig.cacheService())){
            // 1.1 清空缓存中的token
            String cacheHeadKey = buildCatchHeadKey(analysis);
            tokenConfig.cacheService().del(cacheHeadKey);
        }
        return true;
    }

}
